﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace OpenAiClient.Util.IO
{
    public static class FileHelper
    {
        //异步拷贝文件
        public static async Task CopyToAsync(string sourceFileName, string destFileName)
        {
            if (string.IsNullOrWhiteSpace(sourceFileName))
            {
                throw new ArgumentNullException(nameof(sourceFileName));
            }

            if (!File.Exists(sourceFileName))
            {
                throw new FileNotFoundException(sourceFileName);
            }

            using (var sourceStream = File.Open(sourceFileName, FileMode.Open))
            {
                using (var destStream = File.Create(destFileName))
                {
                    await sourceStream.CopyToAsync(destStream);
                }
            }
        }

        //异步写文件
        public static async Task WriteFileAsync(string fileName, string content, CancellationToken token = default)
        {
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            using (var fileStream = File.Create(fileName))
            {
                var buffer = Encoding.UTF8.GetBytes(content);
                await fileStream.WriteAsync(buffer, 0, buffer.Length, token);
            }
        }

        //异步读取文件内容
        public static async Task<string> GetFileContentAsync(string fileName, CancellationToken token = default)
        {
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            if (!File.Exists(fileName))
            {
                throw new FileNotFoundException(fileName);
            }

            using (var fileStream = File.OpenRead(fileName))
            {
                var buffer = new byte[4096];
                var byteList = new List<byte>((int)fileStream.Length);
                while (true)
                {
                    var bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length, token);
                    if (bytesRead <= 0)
                    {
                        break;
                    }

                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    if (bytesRead >= buffer.Length)
                    {
                        byteList.AddRange(buffer);
                    }
                    else
                    {
                        var bytes = new byte[bytesRead];
                        Buffer.BlockCopy(buffer, 0, bytes, 0, bytesRead);
                        byteList.AddRange(bytes);
                    }
                }

                return Encoding.UTF8.GetString(byteList.ToArray());
            }
        }

        //同步读取文件内容
        public static string GetFileContent(string fileName)
        {
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            if (!File.Exists(fileName))
            {
                throw new FileNotFoundException(fileName);
            }

            using (var fileStream = File.Open(fileName, FileMode.Open))
            {
                var buffer = new byte[fileStream.Length];
                var bytesRead = fileStream.Read(buffer, 0, buffer.Length);
                return bytesRead > 0 ? Encoding.UTF8.GetString(buffer) : string.Empty;
            }
        }

        //尝试删除文件
        public static void TryDelete(string fileName)
        {
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentNullException(nameof(fileName));
            }

            if (File.Exists(fileName))
            {
                File.Delete(fileName);
            }
        }
    }
}
